Skip to content

原型式继承(推荐 Es6,过时禁止使用的)

原型式继承是通过使用已有的对象作为新创建对象的原型来实现继承的一种方式。 本质上来说,object 对传入其中的对象执行了一次浅复制

  1. 原型式继承

    • 原型式继承是通过浅复制一个对象来创建一个新对象,然后将新对象的原型指向这个对象,从而实现继承。
    javascript
    var parent = {
      name: "Parent",
      sayHello: function () {
        console.log("Hello, I am " + this.name);
      },
    };
    var child = Object.create(parent); // 原型式继承
    child.name = "Child";
    child.sayHello(); // 输出 "Hello, I am Child"

缺陷例子

  • 共享引用类型值:原型式继承创建的新对象会共享原型对象的属性和方法,包括引用类型值。如果一个对象修改了原型对象中的引用类型值,那么所有继承自该原型的对象都会受到影响,这可能导致意外的结果。

  • 无法传递参数:与构造函数继承类似,原型式继承也无法在创建新对象时向父对象传递参数,因为它并没有调用父对象的构造函数。

  • 难以识别对象类型:由于原型式继承不会创建一个真正的父类实例,因此新对象的类型无法通过 instanceof 等操作符来准确识别。

  • 容易造成对象间耦合:由于新对象直接继承自现有对象,对象之间的耦合性较高。如果原型对象被修改或者污染,所有继承自该原型的对象都会受到影响,导致对象间的关系变得复杂。

js
function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

// 父类构造函数
function Parent() {
  this.colors = ["red", "blue", "green"];
}

// 父类原型方法
Parent.prototype.sayHello = function () {
  console.log("Hello from Parent");
};

// 子类对象,继承自父类
var child1 = Object.create(new Parent());
var child2 = Object.create(new Parent());

// 问题1:共享引用类型值
child1.colors.push("yellow");
console.log(child2.colors); // 输出: ["red", "blue", "green", "yellow"]

// 问题4:难以识别对象类型
console.log(child1 instanceof Parent); // 输出: true,但无法准确识别为子类类型

// 问题5:容易造成对象间耦合
child1.sayHello = function () {
  console.log("Modified Hello from Parent");
};
child1.sayHello(); // 输出: Modified Hello from Parent,所有继承自原型的对象都受到影响